package com.factory.websocket;

import com.factory.MyApplication;
import com.factory.domain.deviceTable;
import com.factory.mapper.DeviceTableMapper;
import com.factory.mapper.SocketDataMapper;
import com.factory.socket.S7MultiDBHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 前后端交互的类实现消息的接收推送
 *
 * @ServerEndpoint(value = "/test/one") 前端通过此URI和后端交互，建立连接
 * orgId 机构id
 */
@ServerEndpoint(value = "/ship_ws/{id}")
@Component
public class WebSocketEndpoint extends ChannelInboundHandlerAdapter {
    private static final Logger log = LoggerFactory.getLogger(MyApplication.class);
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static final AtomicInteger onlineNum = new AtomicInteger();

    /**
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session session;

    //群发送消息
    public void sendManyMessage(String message) {
        ConcurrentHashMap<String, List<Session>> SessionMap = SessionListUtis.getAll();
        for (String key : SessionMap.keySet()) {
            sendInfo(key, message);
        }
    }

    //给指定用户发送信息
    public void sendInfo(String id, String message) {
        List<Session> sessions = SessionListUtis.getHashMap(id);
        if (sessions != null) {
            for (Session value : sessions) {
                try {
                    synchronized (value) {
                        value.getBasicRemote().sendText(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //回复当前心跳消息
    public void sendMessage(String message) throws IOException {
        if (this.session != null) {
            synchronized (this.session) {
                log.info("给当前连接客户端主动发送数据：" + message);
                this.session.getBasicRemote().sendText(message);
            }
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "id") String id) {
        this.session = session;
        List<Session> list = SessionListUtis.getHashMap(id);
        if (list == null) {
            List<Session> sessions = new ArrayList<>();
            sessions.add(session);
            SessionListUtis.setHashMap(id, sessions);
        } else {
            list.add(session);
            SessionListUtis.setHashMap(id, list);
        }
        addOnlineCount();
        log.info(id + "建立链接。当前链接数：" + onlineNum);
        try {
            sendInfo(id, "-----------" + id + "加入连接！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //关闭连接时调用
    @OnClose
    public void onClose(Session session, @PathParam(value = "id") String id) {
        SessionListUtis.remove(id, session);
        subOnlineCount();
//        log.error(id + "断开webSocket链接。当前连接数：" + onlineNum);
    }

    //收到客户端信息
    public static Long mark;
    public static Long deviceId;
    public static String context;
    public static int systemID;


    @OnMessage
    public void onMessage(String message) {
        log.info("服务端收到客户端消息：+++++{}", message);
        /**
         * 收到前端发送过来的数据
         **/
        JSONObject jsonObject = new JSONObject(message);
        //判断属于哪个系统
        mark = jsonObject.getLong("type");
        //设备的Id
        deviceId = jsonObject.getLong("deviceId");
        //修改内容
        context = jsonObject.getString("context");
        S7MultiDBHandler.writeCurrentData(mark,deviceId,context);
    }

    //错误时调用
    @OnError
    public void onError(Session ignoredSession, Throwable throwable) {
        throwable.printStackTrace();
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

}
